#include <QCustomPlot/qcustomplot.h>
#include "widgetone.h"
#include "mytablemodel.h"
#include <eigenhelper.h>
#include "splinefitter.h"
#include "olsfitter.h"


void WidgetOne::initControlPanel() {
    MyWidget::initControlPanel();


    QStringList type{u8"第一类边界条件", u8"第二类边界条件", u8"第三类边界条件"};
    m_comboDoundary->addItems(type);

    m_spinLeft->setMinimum(-100.0);
    m_spinLeft->setMaximum(100.0);

    m_spinRight->setMinimum(-100.0);
    m_spinRight->setMaximum(100.0);

    m_layoutControl->addWidget(new QLabel(u8"边界条件"), 1, 0);
    m_layoutControl->addWidget(new QLabel(u8"最左边一阶导"), 2, 0);
    m_layoutControl->addWidget(new QLabel(u8"最右边一阶导"), 3, 0);

}


QPointF WidgetOne::fitRange() {
    return {m_model1->xMin(), m_model1->xMax()};
}

void WidgetOne::connectSingals() {

    MyWidget::connectSingals();


    connect(m_btnOpen, &QPushButton::clicked, [this]() {
        auto fileName = QFileDialog::getOpenFileName(this, "打开数据", ".", "CSV文件 (*.csv);;文本文件 (*.txt)");
        if (!fileName.isEmpty()) {
            bool ret = m_model1->setFromCsv(fileName);
            if (!ret) {
                QMessageBox::critical(this, "文件存在错误",
                                      QString("无法打开文件\"%1\"，请检查程序是否有权限读取"
                                              "或者文件内容是否满足规范！").arg(fileName),
                                      QMessageBox::Ok);
            } else {
                m_spinLeft->setMinimum(m_model1->xMin());
                m_spinRight->setMaximum(m_model1->xMax());
            }
        }
    });

    connect(m_comboDoundary, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
        m_spinLeft->setEnabled(index == 1);
        m_spinRight->setEnabled(index == 1);
        setParamater();
        reset();
    });


    connect(m_spinLeft, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &WidgetOne::reset);
    connect(m_spinRight, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &WidgetOne::reset);

}
void WidgetOne::refit(){
    MyWidget::refit();
    auto xx_range = fitRange();
    Eigen::VectorXd xx = Eigen::VectorXd::LinSpaced(
            m_fitPointsCount, xx_range.x(), xx_range.y());
    auto yy = m_abstractFitter[0](xx);
    auto xx_arrd = xx.array();
    auto yy_arrd = yy.array();

    auto n = xx_arrd.size() - 1;

    auto length = (
            (xx_arrd.head(n) - xx_arrd.tail(n)).pow(2) +
            (yy_arrd.head(n) - yy_arrd.tail(n)).pow(2)
    ).sqrt().sum();
    m_labPerimeter->setText(QString("曲线总长度: %1").arg(QString::number(length, 'f', 2)));
    m_spinEval->setEnabled(true);
    m_spinEval->setRange(xx_range.x(), xx_range.y());

}

WidgetOne::WidgetOne(QWidget *parent)
        : MyWidget(parent) {

//    这几个初始化函数存在依赖关系，不要随便改变顺序
    WidgetOne::initControlPanel();
    WidgetOne::initTableView();
    WidgetOne::initPlotCanvas(1);
    WidgetOne::connectSingals();

    auto mainLayout = new QGridLayout;
    mainLayout->addWidget(m_tableView, 0, 0, 2, 1);
    mainLayout->addWidget(m_plot, 0, 1);
    mainLayout->addLayout(m_layoutControl, 1, 1);
    mainLayout->setColumnStretch(1, 1);
    mainLayout->setColumnStretch(0, 0);
    setLayout(mainLayout);
    m_abstractFitter = new SplineFitter;
}

WidgetOne::~WidgetOne() {
    delete m_abstractFitter;
}

void WidgetOne::setParamater() {
    dynamic_cast<SplineFitter *>(m_abstractFitter)->setBoundary(
            static_cast<SplineFitter::BoundValueType>(m_comboDoundary->currentIndex()),
            m_spinLeft->value(),
            m_spinRight->value());
}









